package com.chushouya.common.applet;

import com.alibaba.fastjson.JSONObject;
import com.chushouya.common.config.WxConfig;
import com.chushouya.common.wx.dto.WxMessagePushRequest;
import com.chushouya.common.wx.dto.WxOpenInfo;
import com.general.framework.core.lang.Jsons;
import com.general.framework.core.lang.Strings;
import com.general.framework.core.utils.WxApiRequest;
import com.general.framework.data.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 微信客户端
 */
@Slf4j
@Component
public class WxClientPlus {

    @Resource
    private RedisCache redisCache;

    private String getAccessToken(WxConfig config) {
        String wxAccessTokenKey = Strings.format("wx_access_token_cache:{}", config.getAppId());
        String accessToken;
        if (redisCache.exist(wxAccessTokenKey)) {
            accessToken = redisCache.getCacheObject(wxAccessTokenKey);
        } else {
            accessToken = WxApiRequest.getAccessToken(config.getAppId(), config.getAppSecret());
            redisCache.setCacheObject(wxAccessTokenKey, accessToken,7000L, TimeUnit.SECONDS);
        }
        return accessToken;
    }

    public String getPhoneNumber(WxConfig config, String code) {
        String accessToken = getAccessToken(config);
        final String phoneInfo = WxApiRequest.getPhoneNumber(accessToken, code);
        log.debug("====>phoneInfo:{}", phoneInfo);
        final JSONObject jsonObject = Jsons.parseObject(phoneInfo);
        return Strings.defaultString(jsonObject.getString("purePhoneNumber"));
    }

    public WxOpenInfo getWxOfficialOpenInfo(WxConfig config, String code) {
        final Map<String, Object> userInfo = WxApiRequest.getUserInfoByCode(config.getAppId(), config.getAppSecret(), code);
        log.info("====>userInfo:{}", Jsons.toJsonString(userInfo));
        WxOpenInfo wxOpenInfo = new WxOpenInfo();
        wxOpenInfo.setWxUnionId(Strings.defaultString(userInfo.get("unionid")));
        wxOpenInfo.setWxOpenIdOfficial(Strings.defaultString(userInfo.get("openid")));
        return wxOpenInfo;
    }

    public String getOfficialOpenId(WxConfig config, String code) {
        return WxApiRequest.getOpenIdByCode(config.getAppId(), config.getAppSecret(), code);
    }

    public WxOpenInfo getWxLiteOpenInfo(WxConfig config, String code) {
        final Map<String, Object> wxSession = WxApiRequest.getWxSession(config.getAppId(), config.getAppSecret(), code);
        log.info("====>wxSession:{}", Jsons.toJsonString(wxSession));
        WxOpenInfo wxOpenInfo = new WxOpenInfo();
        wxOpenInfo.setWxUnionId(Strings.defaultString(wxSession.get("unionid")));
        wxOpenInfo.setWxOpenIdLite(Strings.defaultString(wxSession.get("openid")));
        return wxOpenInfo;
    }

    public void pushOfficialMessage(WxConfig config, final WxMessagePushRequest wxMessagePushRequest) {
        final String accessToken = getAccessToken(config);
        // 请求地址
        Map<String, Object> requestParam = new HashMap<>(5);
        requestParam.put("touser", wxMessagePushRequest.getOpenId());
        requestParam.put("template_id", wxMessagePushRequest.getTemplateId());
        requestParam.put("url", wxMessagePushRequest.getLinkPage());
        // 小程序数据
        if (Strings.isNotBlank(wxMessagePushRequest.getLiteLinkPage())) {
            Map<String, Object> miniParam = new HashMap<>(2);
            miniParam.put("appid", config.getAppId());
            miniParam.put("pagepath", wxMessagePushRequest.getLiteLinkPage());
            requestParam.put("miniprogram", miniParam);
        }
        requestParam.put("data", wxMessagePushRequest.getData());
        WxApiRequest.pushOfficialMessage(accessToken, requestParam);
    }

    public void pushSubscribeMessage(WxConfig config, final WxMessagePushRequest wxMessagePushRequest) {
        final String accessToken = getAccessToken(config);
        final Map<String, Object> requestParam = new HashMap<>(5);
        requestParam.put("touser", wxMessagePushRequest.getOpenId());
        requestParam.put("template_id", wxMessagePushRequest.getTemplateId());
        requestParam.put("page", wxMessagePushRequest.getLinkPage());
        requestParam.put("data", wxMessagePushRequest.getData());
        if (Strings.isNotBlank(wxMessagePushRequest.getMiniProgramState())) {
            requestParam.put("miniprogram_state", wxMessagePushRequest.getMiniProgramState());
        }
        WxApiRequest.pushSubscribeMessage(accessToken, requestParam);
    }

    public void pushServiceMessage(WxConfig config, final WxMessagePushRequest wxMessagePushRequest) {
        final String accessToken = getAccessToken(config);
        final Map<String, Object> requestParam = new HashMap<>(2);
        requestParam.put("touser", wxMessagePushRequest.getOpenId());
        Map<String, Object> mpTemplateMsg = new HashMap<>(5);
        mpTemplateMsg.put("appid", config.getAppId());
        mpTemplateMsg.put("templateId", wxMessagePushRequest.getTemplateId());
        mpTemplateMsg.put("url", wxMessagePushRequest.getLinkPage());

        Map<String, String> miniprogram = new HashMap<>(2);
        miniprogram.put("appid", config.getAppId());
        miniprogram.put("pagepath", wxMessagePushRequest.getLiteLinkPage());

        mpTemplateMsg.put("miniprogram", miniprogram);
        mpTemplateMsg.put("data", wxMessagePushRequest.getData());
        requestParam.put("mp_template_msg", mpTemplateMsg);
        log.info(Jsons.toFormatJsonString(requestParam));
        WxApiRequest.pushServiceMessage(accessToken, requestParam);
    }

}
